/**
 * @file adc_measure_adv.c
 * @date 2016-08-18
 *
 * NOTE:
 * This file is generated by DAVE. Any manual modification done to this file will be lost when the code is regenerated.
 *
 * @cond
 ***********************************************************************************************************************
 * ADC_MEASUREMENT_ADV v4.0.14 - Incorporates advanced features of the Versatile Analog to Digital Converter
 *                               to measure analog inputs.
 *
 * Copyright (c) 2015-2016, Infineon Technologies AG
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,are permitted provided that the
 * following conditions are met:
 *
 *   Redistributions of source code must retain the above copyright notice, this list of conditions and the  following
 *   disclaimer.
 *
 *   Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
 *   following disclaimer in the documentation and/or other materials provided with the distribution.
 *
 *   Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote
 *   products derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE  FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  OF THE
 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * To improve the quality of the software, users are encouraged to share modifications, enhancements or bug fixes
 * with Infineon Technologies AG (dave@infineon.com).
 ***********************************************************************************************************************
 *
 * Change History
 * --------------
 *
 * 2015-10-09:
 *     - Initial version for DAVEv4.<BR>
 *
 * 2015-10-20:
 *     - Documentation updated.<BR>
 *
 * 2015-12-15:
 *     - Added support for XMC4300 devices.<BR>
 *
 * 2016-01-18:
 *     - 1.Internal consumption of request source.<BR>
 *     - 2.Support for synchronized conversion reduced from 8 master channels to 4 .<BR>
 *     - 3.Converted the SetBoundary() API from public API to private API .<BR>
 *     - 4.Updated all APIs for the Internal consumption of request source.<BR>
 *
 * 2016-02-05:
 *     - Documentation updated.<BR>
 *
 * 2016-03-18:
 *     - Added consumption of the GLOBAL ICLASS -1 for Sync. Conversions.<BR>
 *     - Added consumption of the result register-0 for subtraction mode.<BR>
 *     - Removed ADC_MEASUREMENT_ADV_SetUniformConversion().<BR>
 *     - New API ADC_MEASUREMENT_ADV_SetIclass() added to configure the GLOBAL ICLASS for Slaves. <BR>
 *
 * 2016-04-26:
 *     - The synchronized conversion in a master slave configuration is currently not supported.<BR>
 *
 * 2016-06-17:
 *     - The synchronized conversion is supported.<BR>
 *     - Modified the Sync initialization sequence to configure the EVAL bits in the slave groups.<BR>
 *
 * 2016-08-18:
 *     - Minimum sample time at low frequencies changed to incorporate Errata ADC_AI.H006 and ADC_AI.H007.
 *
 * @endcond
 *
 */

/***********************************************************************************************************************
 * HEADER FILES
 **********************************************************************************************************************/
#include "adc_measurement_adv.h"

/***********************************************************************************************************************
 * MACROS
 **********************************************************************************************************************/
/* Pointer to the VADC GLOBAL*/
#define ADC_MEASUREMENT_ADV_GLOBAL_PTR ((XMC_VADC_GLOBAL_t *) (void *) VADC)

/* Max value possible with 10 bit resolution is 1023*/
#define ADC_MEASUREMENT_ADV_10_BIT_MAX_VALUE ((uint32_t)1023)

#if (XMC_VADC_SHS_AVAILABLE == 1U)
  /* Pointer to the SHS unit */
  #define ADC_MEASUREMENT_ADV_SHS_PTR ((XMC_VADC_GLOBAL_SHS_t *) (void *) SHS0)
#endif

/** One result register is reserved for FIFO tail and for the FIFO head.
 * This needs to be subtracted from the total required FIFO stages. These head and tail result registers needs different
 * settings based on the UI. The macro is hence helpful to determine the number of intermediate stages for the FIFO
 * buffer. Each of the intermediate stages need to only set the GxRCR.FEN bit.
 */
#define ADC_MEASUREMENT_ADV_RESERVED_REGISTERS ((uint32_t)2)

/** The number of result registers needed for each channel depends on the FIFO selected.
 * Always the ADC_MEASUREMENT_ADV_CHANNEL_t::res_handle varies with the FIFO selection.
 * This Macro depicts the configuration for the Head of the FIFO i.e ADC_MEASUREMENT_ADV_CHANNEL_t::res_handle[0].
 * It always represents the head result register(with FIFO) or the result register (without FIFO) configuration.
 */
#define ADC_MEASUREMENT_ADV_HEAD_RESULT_REG_CONFIG ((uint32_t)0)

/** The number of result registers needed for each channel depends on the FIFO selected.
 * Always the ADC_MEASUREMENT_ADV_CHANNEL_t::res_handle varies with the FIFO selection.
 * This Macro depicts the configuration for the tail of the FIFO i.e ADC_MEASUREMENT_ADV_CHANNEL_t::res_handle[1].
 * It always represents the tail result register of the FIFO.
 */
#define ADC_MEASUREMENT_ADV_TAIL_RESULT_REG_CONFIG ((uint32_t)1)

/* Configure the slave input class as global input class 1*/
#define ADC_MEASUREMENT_ADV_GLOBICLASS1 ((uint32_t)1)


/* Since the SCU is different for various devices a macro is defined here to enable check of clock-ungating*/
#if UC_FAMILY == XMC1
  #define ADC_MEASUREMENT_ADV_CHECK_CLOCK_GATING ((uint32_t)1)
#endif

/***********************************************************************************************************************
 * LOCAL DATA
 **********************************************************************************************************************/
 /* Array of Group pointers*/
 XMC_VADC_GROUP_t *const group_ptrs[XMC_VADC_MAXIMUM_NUM_GROUPS] =
 {
    (VADC_G_TypeDef*)(void*) VADC_G0,
    (VADC_G_TypeDef*)(void*) VADC_G1
 #if (XMC_VADC_MAXIMUM_NUM_GROUPS > 2U)
   ,(VADC_G_TypeDef*)(void*) VADC_G2,
    (VADC_G_TypeDef*)(void*) VADC_G3
 #endif
 };

#ifdef ADC_MEASUREMENT_ADV_FIFO_USED
/**
 * Intermediate FIFO stages needs only the GxRCR.FEN bit to be set.Hence this is generated as a static constant.
 */
static const XMC_VADC_RESULT_CONFIG_t ADC_MEASUREMENT_ADV_fifo_intermediate_stage =
{
    .data_reduction_control = 0,
    .post_processing_mode   = 0,
    .wait_for_read_mode     = 0,
    .part_of_fifo           = (bool)true,
    .event_gen_enable       = 0
};
#endif

/*Anonymous structure/union guard start*/
#if defined(__CC_ARM)
  #pragma push
  #pragma anon_unions
#elif defined(__TASKING__)
  #pragma warning 586
#endif

/* Private structure to determine the ALIAS*/
typedef struct ADC_MEASUREMENT_ADV_ALIAS
{
  union
  {
    struct
    {
      uint32_t alias0 : 5; /* ALIAS for Channel 0*/
      uint32_t        : 3;
      uint32_t alias1 : 5; /* ALIAS for channel 1*/
      uint32_t        : 19;
    };
    uint32_t alias;
  };
}ADC_MEASUREMENT_ADV_ALIAS_t;

/*Anonymous structure/union guard end*/
#if defined(__CC_ARM)
  #pragma pop
#elif defined(__TASKING__)
  #pragma warning restore
#endif
/***********************************************************************************************************************
 * LOCAL ROUTINES
 **********************************************************************************************************************/
#if defined(ADC_MEASUREMENT_ADV_ADC_QUEUE_USED) || defined (ADC_MEASUREMENT_ADV_ADC_SCAN_USED)
/* Local function to insert an entry into the H/W*/
__STATIC_INLINE void ADC_MEASUREMENT_ADV_lInsertEntry(const ADC_MEASUREMENT_ADV_t *const handle_ptr, uint8_t ch_num)
{
#if defined( ADC_MEASUREMENT_ADV_SCAN_USED) && defined(ADC_MEASUREMENT_ADV_ADC_SCAN_USED)
  #if defined (ADC_MEASUREMENT_ADV_QUEUE_USED) && defined(ADC_MEASUREMENT_ADV_ADC_QUEUE_USED)
    if ( ADC_MEASUREMENT_ADV_REQUEST_SOURCE_SCAN == handle_ptr->req_src)
  #endif
    {
      ADC_SCAN_InsertScanEntry(handle_ptr->scan_handle, handle_ptr->scan_entries[ch_num]);
    }
#endif
#if defined(ADC_MEASUREMENT_ADV_QUEUE_USED) && defined(ADC_MEASUREMENT_ADV_ADC_QUEUE_USED)
  #if defined(ADC_MEASUREMENT_ADV_SCAN_USED) && defined(ADC_MEASUREMENT_ADV_ADC_SCAN_USED)
    else
  #endif
    {
      ADC_QUEUE_InsertQueueEntry(handle_ptr->queue_handle, handle_ptr->queue_entries[ch_num]);
    }
#endif
}
#endif

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
XMC_VADC_CHANNEL_CONV_t  ADC_MEASUREMENT_ADV_lGetIclass(const ADC_MEASUREMENT_ADV_t *const handle_ptr)
{
  XMC_VADC_CHANNEL_CONV_t req_iclass;

#ifdef ADC_MEASUREMENT_ADV_SCAN_USED
  #ifdef ADC_MEASUREMENT_ADV_QUEUE_USED
    if ( ADC_MEASUREMENT_ADV_REQUEST_SOURCE_LOCAL_SCAN >= handle_ptr->req_src)
  #endif
    {
#ifdef ADC_MEASUREMENT_ADV_LOCAL_SCAN_USED
  #ifdef ADC_MEASUREMENT_ADV_ADC_SCAN_USED
      if ( ADC_MEASUREMENT_ADV_REQUEST_SOURCE_SCAN != handle_ptr->req_src)
  #endif
      {
        req_iclass = (XMC_VADC_CHANNEL_CONV_t)handle_ptr->local_scan_handle->iclass_num;
      }
#endif

#ifdef ADC_MEASUREMENT_ADV_ADC_SCAN_USED
  #ifdef ADC_MEASUREMENT_ADV_LOCAL_SCAN_USED
      else
  #endif
      {
        /* Call the function to initialise Clock and ADC global functional units*/
        req_iclass = (XMC_VADC_CHANNEL_CONV_t)handle_ptr->scan_handle->iclass_num;
      }
#endif
    }
#endif

#ifdef ADC_MEASUREMENT_ADV_QUEUE_USED
  #ifdef ADC_MEASUREMENT_ADV_SCAN_USED
    else
  #endif
    {
#ifdef ADC_MEASUREMENT_ADV_LOCAL_QUEUE_USED
  #ifdef ADC_MEASUREMENT_ADV_ADC_QUEUE_USED
      if ( ADC_MEASUREMENT_ADV_REQUEST_SOURCE_QUEUE != handle_ptr->req_src)
  #endif
      {
        req_iclass = (XMC_VADC_CHANNEL_CONV_t)handle_ptr->local_queue_handle->iclass_num;
      }
#endif

#ifdef ADC_MEASUREMENT_ADV_ADC_QUEUE_USED
  #ifdef ADC_MEASUREMENT_ADV_LOCAL_QUEUE_USED
      else
  #endif
      {
        req_iclass = (XMC_VADC_CHANNEL_CONV_t)handle_ptr->queue_handle->iclass_num;
      }
#endif
    }
#endif
    return (req_iclass);
}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#ifdef ADC_MEASUREMENT_ADV_SYNC_USED

/* Helper function to configure the eval bits in the slave*/
void ADC_MEASUREMENT_ADV_lSyncEvalConfig(uint32_t master_group, uint32_t slave_selected,
                                         uint32_t sync_group)
{
  int8_t group_index;
  sync_group |= (1U << master_group);
  sync_group &= ~(1U << slave_selected);
  for( group_index = XMC_VADC_MAXIMUM_NUM_GROUPS - (int32_t)1; group_index >= (int32_t)0  ; group_index--)
  {
    if ( (bool)false != (bool)((sync_group >> group_index) & 0x1 ))
    {
      XMC_VADC_GROUP_SetSyncSlaveReadySignal(group_ptrs[slave_selected], slave_selected, group_index);
    }
  }
}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* Helper function to execute the sync init sequence*/
void ADC_MEASUREMENT_ADV_lSyncSequencer(const ADC_MEASUREMENT_ADV_t *const handle_ptr,
                                        uint32_t sync_group,
                                        ADC_MEASUREMENT_ADV_SYNC_SEQ_t sequence)
{
  int8_t group_index;
  for( group_index = XMC_VADC_MAXIMUM_NUM_GROUPS - (int32_t)1; group_index >= (int32_t)0  ; group_index--)
  {
    if ( (bool)false != (bool)((sync_group >> group_index) & 0x1 ))
    {
      switch( sequence)
      {
        case ADC_MEASUREMENT_ADV_SYNC_SEQ_POWER_DOWN:
             XMC_VADC_GROUP_SetPowerMode(group_ptrs[group_index],XMC_VADC_GROUP_POWERMODE_OFF);
             break;
        case ADC_MEASUREMENT_ADV_SYNC_SEQ_STSEL_CONFIG:
             XMC_VADC_GROUP_SetSyncSlave(group_ptrs[group_index], handle_ptr->group_index, group_index);
             XMC_VADC_GROUP_CheckSlaveReadiness(group_ptrs[handle_ptr->group_index],group_index);
             break;
        case ADC_MEASUREMENT_ADV_SYNC_SEQ_EVAL_CONFIG:
             ADC_MEASUREMENT_ADV_lSyncEvalConfig(handle_ptr->group_index, group_index, sync_group);
        default:
             break;
      }
    }
  }
}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* Initialization of the all the sync related functions */
__STATIC_INLINE void ADC_MEASUREMENT_ADV_lSyncInit(const ADC_MEASUREMENT_ADV_t *const handle_ptr)
{
  uint8_t sync_group;

  /* shift to get the 4 bit position needed to or it with the slave groups */
  sync_group = handle_ptr->sync_slaves | ( 1 << handle_ptr->group_index);
  ADC_MEASUREMENT_ADV_lSyncSequencer(handle_ptr, sync_group, ADC_MEASUREMENT_ADV_SYNC_SEQ_POWER_DOWN);

  sync_group = handle_ptr->sync_slaves;
  ADC_MEASUREMENT_ADV_lSyncSequencer(handle_ptr, sync_group, ADC_MEASUREMENT_ADV_SYNC_SEQ_STSEL_CONFIG);
  ADC_MEASUREMENT_ADV_lSyncSequencer(handle_ptr, sync_group, ADC_MEASUREMENT_ADV_SYNC_SEQ_EVAL_CONFIG);

  /* Configure the iclass settings needed for the sync slaves*/
  if( (bool) false != handle_ptr->configure_globiclass1)
  {
    ADC_MEASUREMENT_ADV_SetIclass(handle_ptr);
  }

  XMC_VADC_GROUP_SetSyncMaster(group_ptrs[handle_ptr->group_index]);

  XMC_VADC_GROUP_SetPowerMode(group_ptrs[handle_ptr->group_index],XMC_VADC_GROUP_POWERMODE_NORMAL);
}
#endif

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#ifdef ADC_MEASUREMENT_ADV_LOCAL_SCAN_USED
__STATIC_INLINE ADC_MEASUREMENT_ADV_STATUS_t ADC_MEASUREMENT_ADV_lScanInit(ADC_MEASUREMENT_ADV_SCAN_t *const handle_ptr,
                                                           uint8_t group_index)
{
  ADC_MEASUREMENT_ADV_STATUS_t status;

  /*Initialization of APP 'ADCGroup'*/
  status = (ADC_MEASUREMENT_ADV_STATUS_t) GLOBAL_ADC_Init(ADC_MEASUREMENT_ADV_GLOBAL_HANDLE);

  XMC_VADC_GROUP_InputClassInit(group_ptrs[group_index], handle_ptr->iclass_config_handle,
                                XMC_VADC_GROUP_CONV_STD, (uint32_t)handle_ptr->iclass_num);


  /*Initialization of scan request source*/
  XMC_VADC_GROUP_ScanInit(group_ptrs[group_index], handle_ptr->scan_config_handle);

  /* Configure the gating mode for Scan*/
  XMC_VADC_GROUP_ScanSetGatingMode(group_ptrs[group_index], handle_ptr->gating_mode);

  /*Interrupt Configuration*/
  if ((bool)true == handle_ptr->rs_intr_handle.interrupt_enable)
  {
#if (UC_FAMILY == XMC1)
    NVIC_SetPriority((IRQn_Type)handle_ptr->rs_intr_handle.node_id, handle_ptr->rs_intr_handle.priority);
#else
    NVIC_SetPriority((IRQn_Type)handle_ptr->rs_intr_handle.node_id,
                      NVIC_EncodePriority(NVIC_GetPriorityGrouping(),
                      handle_ptr->rs_intr_handle.priority,handle_ptr->rs_intr_handle.sub_priority));
#endif
#ifdef ADC_MEASUREMENT_ADV_NON_DEFAULT_IRQ_SOURCE_SELECTED
    XMC_SCU_SetInterruptControl(handle_ptr->rs_intr_handle.node_id,
                                ((handle_ptr->rs_intr_handle.node_id << 8) | handle_ptr->rs_intr_handle.irqctrl));
#endif

    /* Connect RS Events to NVIC nodes */
    XMC_VADC_GROUP_ScanSetReqSrcEventInterruptNode(group_ptrs[group_index], handle_ptr->srv_req_node);
  }

  return (status);
}
#endif
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#ifdef ADC_MEASUREMENT_ADV_LOCAL_QUEUE_USED
__STATIC_INLINE ADC_MEASUREMENT_ADV_STATUS_t ADC_MEASUREMENT_ADV_lQueueInit(ADC_MEASUREMENT_ADV_QUEUE_t *const handle_ptr,
                                                           uint8_t group_index)
{
  ADC_MEASUREMENT_ADV_STATUS_t status;

  /*Initialization of APP 'GLOBAL_ADC'*/
  status = (ADC_MEASUREMENT_ADV_STATUS_t) GLOBAL_ADC_Init(ADC_MEASUREMENT_ADV_GLOBAL_HANDLE);

  /*Class Configuration*/
  XMC_VADC_GROUP_InputClassInit(group_ptrs[group_index],handle_ptr->iclass_config_handle,
                                XMC_VADC_GROUP_CONV_STD,handle_ptr->iclass_num);

  /* Initialize the Queue hardware */
  XMC_VADC_GROUP_QueueInit(group_ptrs[group_index],handle_ptr->queue_config_handle);

  /* Configure the gating mode for queue*/
  XMC_VADC_GROUP_QueueSetGatingMode(group_ptrs[group_index], handle_ptr->gating_mode);

  /*Interrupt Configuration*/
  if ((bool)true == handle_ptr->rs_intr_handle.interrupt_enable)
  {
#if (UC_FAMILY == XMC1)
    NVIC_SetPriority((IRQn_Type)handle_ptr->rs_intr_handle.node_id, handle_ptr->rs_intr_handle.priority);
#else
    NVIC_SetPriority((IRQn_Type)handle_ptr->rs_intr_handle.node_id,
                      NVIC_EncodePriority(NVIC_GetPriorityGrouping(),
                      handle_ptr->rs_intr_handle.priority,handle_ptr->rs_intr_handle.sub_priority));
#endif
#ifdef ADC_MEASUREMENT_ADV_NON_DEFAULT_IRQ_SOURCE_SELECTED
    XMC_SCU_SetInterruptControl(handle_ptr->rs_intr_handle.node_id,
                                ((handle_ptr->rs_intr_handle.node_id << 8) | handle_ptr->rs_intr_handle.irqctrl));
#endif

    /* Connect RS Events to NVIC nodes */
    XMC_VADC_GROUP_QueueSetReqSrcEventInterruptNode(group_ptrs[group_index], (XMC_VADC_SR_t)handle_ptr->srv_req_node);
  }

  return (status);
}
#endif
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* Local function to do the request source initialization.*/
__STATIC_INLINE ADC_MEASUREMENT_ADV_STATUS_t ADC_MEASUREMENT_ADV_lRequestSrcInit(const ADC_MEASUREMENT_ADV_t
                                                                                 *const handle_ptr)
{
  ADC_MEASUREMENT_ADV_STATUS_t status;

#ifdef ADC_MEASUREMENT_ADV_SCAN_USED
  #ifdef ADC_MEASUREMENT_ADV_QUEUE_USED
    if ( ADC_MEASUREMENT_ADV_REQUEST_SOURCE_LOCAL_SCAN >= handle_ptr->req_src)
  #endif
    {
#ifdef ADC_MEASUREMENT_ADV_LOCAL_SCAN_USED
  #ifdef ADC_MEASUREMENT_ADV_ADC_SCAN_USED
      if ( ADC_MEASUREMENT_ADV_REQUEST_SOURCE_SCAN != handle_ptr->req_src)
  #endif
      {
        status = ADC_MEASUREMENT_ADV_lScanInit(handle_ptr->local_scan_handle,handle_ptr->group_index);
      }
#endif

#ifdef ADC_MEASUREMENT_ADV_ADC_SCAN_USED
  #ifdef ADC_MEASUREMENT_ADV_LOCAL_SCAN_USED
      else
  #endif
      {
        /* Call the function to initialise Clock and ADC global functional units*/
        status = (ADC_MEASUREMENT_ADV_STATUS_t) ADC_SCAN_Init(handle_ptr->scan_handle);
      }
#endif
    }
#endif

#ifdef ADC_MEASUREMENT_ADV_QUEUE_USED
  #ifdef ADC_MEASUREMENT_ADV_SCAN_USED
    else
  #endif
    {
#ifdef ADC_MEASUREMENT_ADV_LOCAL_QUEUE_USED
  #ifdef ADC_MEASUREMENT_ADV_ADC_QUEUE_USED
      if ( ADC_MEASUREMENT_ADV_REQUEST_SOURCE_QUEUE != handle_ptr->req_src)
  #endif
      {
        status = ADC_MEASUREMENT_ADV_lQueueInit(handle_ptr->local_queue_handle,handle_ptr->group_index);
      }
#endif

#ifdef ADC_MEASUREMENT_ADV_ADC_QUEUE_USED
  #ifdef ADC_MEASUREMENT_ADV_LOCAL_QUEUE_USED
      else
  #endif
      {
        /* Call the function to initialise Clock and ADC global functional units*/
        status = (ADC_MEASUREMENT_ADV_STATUS_t) ADC_QUEUE_Init(handle_ptr->queue_handle);
      }
#endif
    }
#endif
    return (status);
}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#ifdef ADC_MEASUREMENT_ADV_LOCAL_QUEUE_USED
/* Local function to insert the queue entries into the hardware.*/
__STATIC_INLINE void ADC_MEASUREMENT_ADV_lQueueInsertEntries(const ADC_MEASUREMENT_ADV_t *const handle_ptr)
{
  uint32_t entry_index;

  XMC_VADC_GROUP_t *queue_group_ptr = group_ptrs[handle_ptr->group_index];
  const XMC_VADC_QUEUE_ENTRY_t **const entries_array = handle_ptr->local_queue_entries;

  for(entry_index = 0; entry_index < handle_ptr->total_number_of_entries; entry_index++)
  {
    XMC_VADC_GROUP_QueueInsertChannel(queue_group_ptr, *entries_array[entry_index]);
  }
}
#endif

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
__STATIC_INLINE bool ADC_MEASUREMENT_ADV_lArbitrationStatus(const ADC_MEASUREMENT_ADV_t *const handle_ptr)
{
  bool clock_reset_check;
  bool arbitration_status;

#if !defined(CLOCK_GATING_SUPPORTED) || !defined(ADC_MEASUREMENT_ADV_CHECK_CLOCK_GATING)
  clock_reset_check = (bool)false;
#endif
  arbitration_status = (bool)false;

  /* To check if the arbiter is already enabled. Before checking this ensure that clock and reset states are correct */
#if defined(CLOCK_GATING_SUPPORTED) && defined(ADC_MEASUREMENT_ADV_CHECK_CLOCK_GATING)
  clock_reset_check = !XMC_SCU_CLOCK_IsPeripheralClockGated(XMC_SCU_PERIPHERAL_CLOCK_VADC);
#endif
#ifdef PERIPHERAL_RESET_SUPPORTED
  clock_reset_check |= !XMC_SCU_RESET_IsPeripheralResetAsserted(XMC_SCU_PERIPHERAL_RESET_VADC);
#endif
  if(clock_reset_check != (bool)false)
  {
#ifdef ADC_MEASUREMENT_ADV_SCAN_USED
  #ifdef ADC_MEASUREMENT_ADV_QUEUE_USED
    if ( ADC_MEASUREMENT_ADV_REQUEST_SOURCE_LOCAL_SCAN >= handle_ptr->req_src)
  #endif
      {
        arbitration_status = XMC_VADC_GROUP_ScanIsArbitrationSlotEnabled(group_ptrs[handle_ptr->group_index]);
      }
#endif

#ifdef ADC_MEASUREMENT_ADV_QUEUE_USED
  #ifdef ADC_MEASUREMENT_ADV_SCAN_USED
      else
  #endif
      {
        arbitration_status = XMC_VADC_GROUP_QueueIsArbitrationSlotEnabled(group_ptrs[handle_ptr->group_index]);
      }
#endif
  }
  return (arbitration_status);
}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
__STATIC_INLINE void ADC_MEASUREMENT_ADV_lDisableArbitration(const ADC_MEASUREMENT_ADV_t *const handle_ptr,
                                                             bool arbitration_status)
{
  if(arbitration_status == (bool)false)
  {
#ifdef ADC_MEASUREMENT_ADV_SCAN_USED
  #ifdef ADC_MEASUREMENT_ADV_QUEUE_USED
      if ( ADC_MEASUREMENT_ADV_REQUEST_SOURCE_LOCAL_SCAN >= handle_ptr->req_src)
  #endif
      {
        XMC_VADC_GROUP_ScanDisableArbitrationSlot(group_ptrs[handle_ptr->group_index]);
      }
#endif

#ifdef ADC_MEASUREMENT_ADV_QUEUE_USED
  #ifdef ADC_MEASUREMENT_ADV_SCAN_USED
      else
  #endif
      {
        XMC_VADC_GROUP_QueueDisableArbitrationSlot(group_ptrs[handle_ptr->group_index]);
      }
#endif
  }
}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* Insert channels into the hardware*/
void ADC_MEASUREMENT_ADV_lInsertChannels(const ADC_MEASUREMENT_ADV_t *const handle_ptr)
{
  XMC_ASSERT("ADC_MEASUREMENT_ADV_InsertChannels:Invalid handle_ptr", (handle_ptr != NULL))

#ifdef ADC_MEASUREMENT_ADV_SCAN_USED
  #ifdef ADC_MEASUREMENT_ADV_QUEUE_USED
    if ( ADC_MEASUREMENT_ADV_REQUEST_SOURCE_LOCAL_SCAN >= handle_ptr->req_src)
  #endif
    {
#ifdef ADC_MEASUREMENT_ADV_LOCAL_SCAN_USED
  #ifdef ADC_MEASUREMENT_ADV_ADC_SCAN_USED
      if ( ADC_MEASUREMENT_ADV_REQUEST_SOURCE_SCAN != handle_ptr->req_src)
  #endif
      {
        XMC_VADC_GROUP_ScanAddMultipleChannels(group_ptrs[handle_ptr->group_index], handle_ptr->local_scan_handle->insert_mask);
      }
#endif

#ifdef ADC_MEASUREMENT_ADV_ADC_SCAN_USED
  #ifdef ADC_MEASUREMENT_ADV_LOCAL_SCAN_USED
      else
  #endif
      {
        ADC_SCAN_AllEntriesInserted(handle_ptr->scan_handle);
      }
#endif
    }
#endif

#ifdef ADC_MEASUREMENT_ADV_QUEUE_USED
  #ifdef ADC_MEASUREMENT_ADV_SCAN_USED
    else
  #endif
    {
#ifdef ADC_MEASUREMENT_ADV_LOCAL_QUEUE_USED
  #ifdef ADC_MEASUREMENT_ADV_ADC_QUEUE_USED
      if ( ADC_MEASUREMENT_ADV_REQUEST_SOURCE_QUEUE != handle_ptr->req_src)
  #endif
      {
        ADC_MEASUREMENT_ADV_lQueueInsertEntries(handle_ptr);
      }
#endif

#ifdef ADC_MEASUREMENT_ADV_ADC_QUEUE_USED
  #ifdef ADC_MEASUREMENT_ADV_LOCAL_QUEUE_USED
      else
  #endif
      {
        ADC_QUEUE_AllEntriesInserted(handle_ptr->queue_handle);
      }
#endif
    }
#endif
}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* Select the boundary for a channel and configure its value as well.*/
void ADC_MEASUREMENT_ADV_lSetBoundary(const ADC_MEASUREMENT_ADV_CHANNEL_t *const handle_ptr,
                                     XMC_VADC_CHANNEL_BOUNDARY_t boundary_select,
                                     uint32_t boundary_value)
{
  XMC_ASSERT("ADC_MEASUREMENT_ADV_SetBoundary:Invalid handle_ptr", (handle_ptr != NULL))

  switch(boundary_select)
  {
    case XMC_VADC_CHANNEL_BOUNDARY_GROUP_BOUND0:
    case XMC_VADC_CHANNEL_BOUNDARY_GROUP_BOUND1:
         XMC_VADC_GROUP_SetIndividualBoundary(group_ptrs[handle_ptr->group_index], boundary_select,
                                              (uint16_t)boundary_value);
         break;

    case XMC_VADC_CHANNEL_BOUNDARY_GLOBAL_BOUND0:
    case XMC_VADC_CHANNEL_BOUNDARY_GLOBAL_BOUND1:
         XMC_VADC_GLOBAL_SetIndividualBoundary(ADC_MEASUREMENT_ADV_GLOBAL_PTR,
                                               boundary_select,
                                               (uint16_t)boundary_value);
         break;
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#ifndef ADC_MEASUREMENT_ADV_SYNC_USED
/* Address the errata for the incorrect conversion.*/
void ADC_MEASUREMENT_ADV_lSyncADCClocks(void)
{
  int32_t group_index;

  for (group_index = (int32_t)XMC_VADC_MAXIMUM_NUM_GROUPS - (int32_t)1; group_index >= (int32_t)0  ; group_index--)
  {
    XMC_VADC_GROUP_SetPowerMode(group_ptrs[group_index],XMC_VADC_GROUP_POWERMODE_OFF);
  }

  for (group_index = (int32_t)XMC_VADC_MAXIMUM_NUM_GROUPS - (int32_t)1; group_index > (int32_t)0  ; group_index--)
  {
    XMC_VADC_GROUP_SetSyncSlave(group_ptrs[group_index], (uint32_t)0, (uint32_t)group_index);

    XMC_VADC_GROUP_CheckSlaveReadiness(group_ptrs[0U], (uint32_t)group_index);
  }

  XMC_VADC_GROUP_SetSyncMaster(group_ptrs[0U]);

  XMC_VADC_GROUP_SetPowerMode(group_ptrs[0U],XMC_VADC_GROUP_POWERMODE_NORMAL);
}
#endif
/**********************************************************************************************************************
 * API IMPLEMENTATION
 **********************************************************************************************************************/

/*This function returns the version of the ADC_MEASUREMENT App*/
DAVE_APP_VERSION_t ADC_MEASUREMENT_ADV_GetAppVersion(void)
{
  DAVE_APP_VERSION_t version;

  version.major = (uint8_t) ADC_MEASUREMENT_ADV_MAJOR_VERSION;
  version.minor = (uint8_t) ADC_MEASUREMENT_ADV_MINOR_VERSION;
  version.patch = (uint8_t) ADC_MEASUREMENT_ADV_PATCH_VERSION;

  return version;
}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* Enables the arbiter of the selected request source*/
void ADC_MEASUREMENT_ADV_StartADC(const ADC_MEASUREMENT_ADV_t *const handle_ptr)
{
#ifdef ADC_MEASUREMENT_ADV_SCAN_USED
  #ifdef ADC_MEASUREMENT_ADV_QUEUE_USED
    if ( ADC_MEASUREMENT_ADV_REQUEST_SOURCE_LOCAL_SCAN >= handle_ptr->req_src)
  #endif
      {
        XMC_VADC_GROUP_ScanEnableArbitrationSlot(group_ptrs[handle_ptr->group_index]);
      }
#endif

#ifdef ADC_MEASUREMENT_ADV_QUEUE_USED
  #ifdef ADC_MEASUREMENT_ADV_SCAN_USED
      else
  #endif
      {
        XMC_VADC_GROUP_QueueEnableArbitrationSlot(group_ptrs[handle_ptr->group_index]);
      }
#endif
}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* Starts the ADC conversions by causing a software start of conversion*/
void ADC_MEASUREMENT_ADV_SoftwareTrigger(const ADC_MEASUREMENT_ADV_t *const handle_ptr)
{
  XMC_ASSERT("ADC_MEASUREMENT_ADV_StartConversion:Invalid handle_ptr", (handle_ptr != NULL))

#ifdef ADC_MEASUREMENT_ADV_SCAN_USED
  #ifdef ADC_MEASUREMENT_ADV_QUEUE_USED
    if ( ADC_MEASUREMENT_ADV_REQUEST_SOURCE_LOCAL_SCAN >= handle_ptr->req_src)
  #endif
    {
      XMC_VADC_GROUP_ScanTriggerConversion(group_ptrs[handle_ptr->group_index]);
    }
#endif
#ifdef ADC_MEASUREMENT_ADV_QUEUE_USED
  #ifdef ADC_MEASUREMENT_ADV_SCAN_USED
    else
  #endif
    {
      XMC_VADC_GROUP_QueueTriggerConversion(group_ptrs[handle_ptr->group_index]);
    }
#endif
}


/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* Enables the NVIC(if needed) when scan/queue request source is consumed internally in the APP. */
void ADC_MEASUREMENT_ADC_lNvicEnable(const ADC_MEASUREMENT_ADV_t *const handle_ptr)
{
#ifdef ADC_MEASUREMENT_ADV_LOCAL_SCAN_USED
    if (((bool)true == handle_ptr->local_scan_handle->rs_intr_handle.interrupt_enable) &&
        (ADC_MEASUREMENT_ADV_REQUEST_SOURCE_LOCAL_SCAN == handle_ptr->req_src))
    {
      NVIC_EnableIRQ((IRQn_Type)handle_ptr->local_scan_handle->rs_intr_handle.node_id);
    }
#endif
#ifdef ADC_MEASUREMENT_ADV_LOCAL_QUEUE_USED
    if (((bool)true == handle_ptr->local_queue_handle->rs_intr_handle.interrupt_enable) &&
        (ADC_MEASUREMENT_ADV_REQUEST_SOURCE_LOCAL_QUEUE == handle_ptr->req_src))
    {
      NVIC_EnableIRQ((IRQn_Type)handle_ptr->local_queue_handle->rs_intr_handle.node_id);
    }
#endif
}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* Configures the result results . */
__STATIC_INLINE void ADC_MEASUREMENT_ADC_lResultInit(const ADC_MEASUREMENT_ADV_CHANNEL_t *indexed)
{
#ifdef ADC_MEASUREMENT_ADV_FIFO_USED
  uint8_t fifo_num_of_intermediate_stages;
  uint8_t fifo_index;
  uint8_t fifo_head;
#endif
#ifdef ADC_MEASUREMENT_ADV_FIFO_USED
  /* If FIFO is selected for the particular channel then do the FIFO initializations*/
  if ( (uint32_t)0 != indexed->max_fifo_required)
  {
    /*Excluding the head and tail from the total number of FIFO elements needed*/
    fifo_num_of_intermediate_stages = indexed->max_fifo_required - ADC_MEASUREMENT_ADV_RESERVED_REGISTERS;

    fifo_head = (uint8_t)indexed->ch_handle->result_reg_number;
    for (fifo_index = 1; fifo_index <= fifo_num_of_intermediate_stages; fifo_index++)
    {
      XMC_VADC_GROUP_ResultInit(group_ptrs[indexed->group_index], (uint32_t)fifo_head - fifo_index,
                                &ADC_MEASUREMENT_ADV_fifo_intermediate_stage);
      }

     /* For the FIFO Tail configuration*/
      XMC_VADC_GROUP_ResultInit(group_ptrs[indexed->group_index], (uint32_t)indexed->result_fifo_tail_number,
                                indexed->res_handle[ADC_MEASUREMENT_ADV_TAIL_RESULT_REG_CONFIG]);
  }
#endif
      /* Initialize for configured result registers For FIFO Head configuration*/
      XMC_VADC_GROUP_ResultInit(group_ptrs[indexed->group_index], (uint32_t)indexed->ch_handle->result_reg_number,
                                indexed->res_handle[ADC_MEASUREMENT_ADV_HEAD_RESULT_REG_CONFIG]);
}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* Initialization routine to call ADC LLD API's */
ADC_MEASUREMENT_ADV_STATUS_t ADC_MEASUREMENT_ADV_Init(const ADC_MEASUREMENT_ADV_t *const handle_ptr)
{
  XMC_ASSERT("ADC_MEASUREMENT_ADV_Init:Invalid handle_ptr", (handle_ptr != NULL))

  const ADC_MEASUREMENT_ADV_CHANNEL_t *indexed;
  uint8_t ch_num;
  uint8_t total_number_of_channels;
  ADC_MEASUREMENT_ADV_STATUS_t status;
#ifdef ADC_MEASUREMENT_ADV_SHS_GAIN_NON_DEFAULT
  uint8_t channel_number;
#endif
  bool arbitration_status = (bool)false;

  if (ADC_MEASUREMENT_ADV_STATUS_UNINITIALIZED == *handle_ptr->init_state)
  {

    arbitration_status = ADC_MEASUREMENT_ADV_lArbitrationStatus(handle_ptr);

   /* Initialize the scan/queue request source.*/
   status = ADC_MEASUREMENT_ADV_lRequestSrcInit(handle_ptr);

   /* Disable the Arbitration if no other instance has enabled it*/
   ADC_MEASUREMENT_ADV_lDisableArbitration(handle_ptr,arbitration_status);

#ifdef ADC_MEASUREMENT_ADV_SYNC_USED
  #ifdef ADC_MEASUREMENT_ADV_SYNC_NOT_ALL_USED
    if ((uint32_t)0 != handle_ptr->sync_slaves)
  #endif
    {
      /*  Configure the Sync conversion operation */
      ADC_MEASUREMENT_ADV_lSyncInit(handle_ptr);
    }
#else
   ADC_MEASUREMENT_ADV_lSyncADCClocks();
#endif

    /* Initialize the SR lines for the Channel event and the Result event, if required*/
#ifdef ADC_MEASUREMENT_ADV_MUX_USED
  #ifdef ADC_MEASUREMENT_ADV_MUX_NOT_ALL_USED
    if (handle_ptr->event_config != NULL)
  #endif
    {
      (handle_ptr->event_config)();
    }
#endif

    total_number_of_channels = (uint8_t)handle_ptr->total_number_of_channels;
    for (ch_num = (uint8_t)0; ch_num < (uint8_t)total_number_of_channels; ch_num++)
    {
      indexed = handle_ptr->channel_array[ch_num];

      /* Initialize for configured channels*/
      XMC_VADC_GROUP_ChannelInit(group_ptrs[indexed->group_index],(uint32_t)indexed->ch_num, indexed->ch_handle);

#if (XMC_VADC_SHS_AVAILABLE == 1U)
  #ifdef ADC_MEASUREMENT_ADV_SHS_GAIN_NON_DEFAULT
      channel_number = indexed->ch_num;
    #ifdef ADC_MEASUREMENT_ADV_SHS_GAIN_ALIAS
      if (indexed->ch_handle->alias_channel != XMC_VADC_CHANNEL_ALIAS_DISABLED)
      {
         channel_number = indexed->ch_handle->alias_channel;
      }
    #endif
      XMC_VADC_GLOBAL_SHS_SetGainFactor(ADC_MEASUREMENT_ADV_SHS_PTR,
                                        (uint8_t)indexed->shs_gain_factor,
                                        (XMC_VADC_GROUP_INDEX_t)indexed->group_index,
                                        channel_number);
  #endif
#endif

      /* Result Init both with and without FIFO */
      ADC_MEASUREMENT_ADC_lResultInit(indexed);

#ifdef ADC_MEASUREMENT_ADV_ANALOG_IO_USED
      /* ANALOG_IO initialization for the channel*/
#ifndef ADC_MEASUREMENT_ADV_ANALOG_IO_ALL_CHANNELS_USED
      if(indexed->analog_io_config != NULL)
#endif
      {
        status |= (ADC_MEASUREMENT_ADV_STATUS_t) ANALOG_IO_Init(indexed->analog_io_config);
      }
#endif
    }

#if defined(ADC_MEASUREMENT_ADV_ADC_SCAN_USED) || defined(ADC_MEASUREMENT_ADV_ADC_QUEUE_USED)
    /* Load the queue/scan entries into ADC_QUEUE/ADC_SCAN.
     * This would load the scan/ queue entries into the software buffers in the ADC_SCAN/ADC_QUEUE APPs.
     * A call to this API would only configure the ADC_SCAN/ADC_QUEUE software buffers and will not be
     * programmed into the Hardware. The programming into the hardware is taken care by another API.
     */
#if defined(ADC_MEASUREMENT_ADV_LOCAL_SCAN_USED) || defined(ADC_MEASUREMENT_ADV_LOCAL_QUEUE_USED)
    if( (ADC_MEASUREMENT_ADV_REQUEST_SOURCE_SCAN == handle_ptr->req_src) ||
        (ADC_MEASUREMENT_ADV_REQUEST_SOURCE_QUEUE == handle_ptr->req_src))
#endif
    {
      for (ch_num = (uint8_t)0; ch_num < (uint8_t)handle_ptr->total_number_of_entries; ch_num++)
      {
        ADC_MEASUREMENT_ADV_lInsertEntry(handle_ptr,ch_num);
      }
    }
#endif

    /* Enables the NVIC node if NVIC node is consumed inside the APP*/
    ADC_MEASUREMENT_ADC_lNvicEnable(handle_ptr);

    /* Load the queue/scan entries into the hardware */
    ADC_MEASUREMENT_ADV_lInsertChannels(handle_ptr);

    /*Start the arbiter of the ADC request source after the initialization. */
#ifdef ADC_MEASUREMENT_ADV_START_ADC
  #ifdef ADC_MEASUREMENT_ADV_NOT_ALL_REQ_START
    if ((bool)false  != handle_ptr->start_at_initialization)
  #endif
    {
      ADC_MEASUREMENT_ADV_StartADC(handle_ptr);
    }
#endif

    *handle_ptr->init_state = status;
  }
  return (*handle_ptr->init_state);
}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* Set the Fast compare value*/
ADC_MEASUREMENT_ADV_STATUS_t ADC_MEASUREMENT_ADV_SetFastCompareValue(const ADC_MEASUREMENT_ADV_CHANNEL_t
                                                                     *const handle_ptr, uint16_t compare_value)
{
  ADC_MEASUREMENT_ADV_STATUS_t status;
  XMC_ASSERT("ADC_MEASUREMENT_ADV_SetFastCompareValue:Invalid handle_ptr", (handle_ptr != NULL))

  status = ADC_MEASUREMENT_ADV_STATUS_FAILURE;

  if ( (uint32_t)compare_value <= ADC_MEASUREMENT_ADV_10_BIT_MAX_VALUE)
  {
    XMC_VADC_GROUP_SetResultFastCompareValue(group_ptrs[handle_ptr->group_index],
                                             (uint32_t)  handle_ptr->ch_handle->result_reg_number,
                                             (XMC_VADC_RESULT_SIZE_t)compare_value);
    status = ADC_MEASUREMENT_ADV_STATUS_SUCCESS;
  }
  return (status);
}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* Set the Subtraction value */
void ADC_MEASUREMENT_ADV_SetSubtractionValue(const ADC_MEASUREMENT_ADV_t *const handle_ptr,
                                             ADC_MEASUREMENT_ADV_SUBTRATION_t subtraction_alignment,
                                             uint16_t subtraction_value)
{
  uint32_t groups;
  uint8_t i;
  XMC_ASSERT("ADC_MEASUREMENT_ADV_SetSubtractionValue:Invalid handle_ptr", (handle_ptr != NULL))

#ifdef ADC_MEASUREMENT_ADV_SYNC_USED
  groups = handle_ptr->sync_slaves;
#else
  groups = (uint32_t)0;
#endif
  groups |= (uint32_t)((uint32_t)1 << (uint32_t)handle_ptr->group_index);
  for ( i = (uint8_t)0; i < (uint8_t)XMC_VADC_MAXIMUM_NUM_GROUPS ; i++)
  {
    if ( (bool)false != (bool)((groups >> i) & (uint32_t)0x1 ))
    {
      XMC_VADC_GROUP_SetResultSubtractionValue(group_ptrs[i], (uint16_t)(subtraction_value
                                                                         << (uint32_t)subtraction_alignment));
    }
  }

}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* Configure the resolution and sampling time in an iclass */
void ADC_MEASUREMENT_ADV_ConfigureChannelClass(const ADC_MEASUREMENT_ADV_CHANNEL_t *const handle_ptr,
                                               const XMC_VADC_GROUP_CLASS_t *config)
{
  XMC_ASSERT("ADC_MEASUREMENT_ADV_ConfigureChannelClass:Invalid class configuration", (config != NULL))

  XMC_VADC_GROUP_InputClassInit(group_ptrs[handle_ptr->group_index], *config, XMC_VADC_GROUP_CONV_STD,
                                (uint32_t)handle_ptr->ch_handle->input_class);
}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* Sets the alternate reference for a particular channel*/
void ADC_MEASUREMENT_ADV_SetAlternateReference(const ADC_MEASUREMENT_ADV_CHANNEL_t *const handle_ptr,
                                               const XMC_VADC_CHANNEL_REF_t reference_select)
{
  XMC_ASSERT("ADC_MEASUREMENT_ADV_SetAlternateReference:Invalid handle_ptr", (handle_ptr != NULL))

  XMC_VADC_GROUP_ChannelSetInputReference(group_ptrs[handle_ptr->group_index], (uint32_t)handle_ptr->ch_num,
                                          reference_select);

}

#if (XMC_VADC_SHS_AVAILABLE == 1U)
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* Sets the gain ratio for a particular channel*/
void ADC_MEASUREMENT_ADV_SetChannelGain(const ADC_MEASUREMENT_ADV_CHANNEL_t *const handle_ptr,
                                        const ADC_MEASUREMENT_ADV_GAIN_t gain_factor)
{
  uint8_t channel_number;
  XMC_ASSERT("ADC_MEASUREMENT_ADV_SetChannelGain:Invalid handle_ptr", (handle_ptr != NULL))

  channel_number = handle_ptr->ch_num;
#ifdef ADC_MEASUREMENT_ADV_SHS_GAIN_ALIAS
  if (handle_ptr->ch_handle->alias_channel != XMC_VADC_CHANNEL_ALIAS_DISABLED)
  {
    channel_number = (uint8_t) handle_ptr->ch_handle->alias_channel;
  }
#endif
  XMC_VADC_GLOBAL_SHS_SetGainFactor(ADC_MEASUREMENT_ADV_SHS_PTR,
                                    (uint8_t)gain_factor,
                                    (XMC_VADC_GROUP_INDEX_t)handle_ptr->group_index,
                                    (uint32_t)channel_number);
}
#endif

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* Select the boundary for the channel*/
void ADC_MEASUREMENT_ADV_SelectBoundary(const ADC_MEASUREMENT_ADV_CHANNEL_t *const handle_ptr,
                                        XMC_VADC_BOUNDARY_SELECT_t boundary,
                                        XMC_VADC_CHANNEL_BOUNDARY_t boundary_selection)
{
  XMC_ASSERT("ADC_MEASUREMENT_ADV_SelectBoundary:Invalid handle_ptr", (handle_ptr != NULL))

  XMC_VADC_GROUP_ChannelSetBoundarySelection(group_ptrs[handle_ptr->group_index], (uint32_t)handle_ptr->ch_num,
                                               boundary, boundary_selection);

}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* configure the upper boundary for a channel.*/
void ADC_MEASUREMENT_ADV_SetBoundaryUpper(const ADC_MEASUREMENT_ADV_CHANNEL_t *const handle_ptr,
                                          uint32_t boundary_value)
{
  uint32_t boundary_select;
  XMC_ASSERT("ADC_MEASUREMENT_ADV_SetBoundary:Invalid handle_ptr", (handle_ptr != NULL))

  boundary_select = handle_ptr->ch_handle->upper_boundary_select;

  ADC_MEASUREMENT_ADV_lSetBoundary(handle_ptr, (XMC_VADC_CHANNEL_BOUNDARY_t)boundary_select, boundary_value);
}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* configure the lower boundary for a channel.*/
void ADC_MEASUREMENT_ADV_SetBoundaryLower(const ADC_MEASUREMENT_ADV_CHANNEL_t *const handle_ptr,
                                          uint32_t boundary_value)
{
  uint32_t boundary_select;
  XMC_ASSERT("ADC_MEASUREMENT_ADV_SetBoundary:Invalid handle_ptr", (handle_ptr != NULL))

  boundary_select = handle_ptr->ch_handle->lower_boundary_select;

  ADC_MEASUREMENT_ADV_lSetBoundary(handle_ptr, (XMC_VADC_CHANNEL_BOUNDARY_t)boundary_select, boundary_value);
}


/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* Aliased channel number is returned if the channel has alias enabled */
XMC_VADC_CHANNEL_ALIAS_t ADC_MEASUREMENT_ADV_GetAliasValue(const ADC_MEASUREMENT_ADV_CHANNEL_t *const handle_ptr)
{
  XMC_VADC_CHANNEL_ALIAS_t return_value;
  ADC_MEASUREMENT_ADV_ALIAS_t alias_value;

  XMC_ASSERT("ADC_MEASUREMENT_ADV_GetAliasValue:Invalid handle_ptr", (handle_ptr != NULL))

  alias_value.alias = XMC_VADC_GROUP_GetAlias(group_ptrs[handle_ptr->group_index]);
  if ((uint8_t)0 == handle_ptr->ch_num )
  {
    return_value = (XMC_VADC_CHANNEL_ALIAS_t)alias_value.alias0;
    if ((uint32_t)0 == alias_value.alias0)
    {
      return_value = XMC_VADC_CHANNEL_ALIAS_DISABLED;
    }
  }
  else if ((uint8_t)1 == handle_ptr->ch_num )
  {
    return_value = (XMC_VADC_CHANNEL_ALIAS_t)alias_value.alias1;
    if ((uint32_t)1 == alias_value.alias1)
    {
      return_value = XMC_VADC_CHANNEL_ALIAS_DISABLED;
    }
  }
  else
  {
    return_value = XMC_VADC_CHANNEL_ALIAS_DISABLED;
  }

  return(return_value);

}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

#ifdef ADC_MEASUREMENT_ADV_SYNC_USED
/* Enables uniform conversion configurations across slaves*/
void ADC_MEASUREMENT_ADV_SetIclass(const ADC_MEASUREMENT_ADV_t *const handle_ptr)
{
  XMC_VADC_CHANNEL_CONV_t req_iclass;
  XMC_VADC_GROUP_CLASS_t conv_class;
  XMC_VADC_GLOBAL_CLASS_t conv_class_global;

  XMC_ASSERT("ADC_MEASUREMENT_ADV_SetIclass:Invalid handle_ptr", (handle_ptr != NULL))

  req_iclass = ADC_MEASUREMENT_ADV_lGetIclass(handle_ptr);
  conv_class = XMC_VADC_GROUP_GetInputClass(group_ptrs[handle_ptr->group_index], req_iclass);
  conv_class_global.globiclass = conv_class.g_iclass0;
  XMC_VADC_GLOBAL_InputClassInit(ADC_MEASUREMENT_ADV_GLOBAL_PTR, conv_class_global,
                                 XMC_VADC_GROUP_CONV_STD, (uint32_t)ADC_MEASUREMENT_ADV_GLOBICLASS1);

}
#endif
